"""Sentry error tracking configuration."""
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.redis import RedisIntegration
from sentry_sdk.integrations.celery import CeleryIntegration
from flask import Flask


def setup_sentry(app: Flask):
    """Configure Sentry error tracking.
    
    Args:
        app: Flask application instance
    """
    sentry_dsn = app.config.get('SENTRY_DSN', '')
    
    if not sentry_dsn:
        app.logger.info("Sentry DSN not configured, error tracking disabled")
        return
    
    environment = app.config.get('SENTRY_ENVIRONMENT', 'production')
    
    # Initialize Sentry
    sentry_sdk.init(
        dsn=sentry_dsn,
        environment=environment,
        integrations=[
            FlaskIntegration(),
            SqlalchemyIntegration(),
            RedisIntegration(),
            CeleryIntegration(),
        ],
        
        # Set traces_sample_rate to 1.0 to capture 100% of transactions for performance monitoring.
        # We recommend adjusting this value in production.
        traces_sample_rate=0.1,  # 10% of transactions
        
        # Set profiles_sample_rate to 1.0 to profile 100% of sampled transactions.
        # We recommend adjusting this value in production.
        profiles_sample_rate=0.1,  # 10% of sampled transactions
        
        # Send default PII (Personally Identifiable Information)
        send_default_pii=False,
        
        # Attach stack traces to messages
        attach_stacktrace=True,
        
        # Maximum number of breadcrumbs
        max_breadcrumbs=50,
        
        # Before send callback to filter events
        before_send=before_send_filter,
        
        # Release tracking (use git commit hash or version)
        # release="buyu@1.0.0",
    )
    
    app.logger.info(f"Sentry initialized for environment: {environment}")


def before_send_filter(event, hint):
    """Filter events before sending to Sentry.
    
    Args:
        event: Sentry event dictionary
        hint: Additional information about the event
        
    Returns:
        Modified event or None to drop the event
    """
    # Don't send events for certain exceptions
    if 'exc_info' in hint:
        exc_type, exc_value, tb = hint['exc_info']
        
        # Filter out specific exceptions
        if exc_type.__name__ in ['NotFound', 'Unauthorized', 'BadRequest']:
            return None
    
    # Remove sensitive data from request body
    if 'request' in event:
        if 'data' in event['request']:
            data = event['request']['data']
            if isinstance(data, dict):
                # Remove sensitive fields
                for key in ['password', 'token', 'secret', 'api_key']:
                    if key in data:
                        data[key] = '[FILTERED]'
    
    return event


def capture_exception(error: Exception, context: dict = None):
    """Manually capture an exception to Sentry.
    
    Args:
        error: Exception to capture
        context: Additional context information
    """
    if context:
        with sentry_sdk.push_scope() as scope:
            for key, value in context.items():
                scope.set_context(key, value)
            sentry_sdk.capture_exception(error)
    else:
        sentry_sdk.capture_exception(error)


def capture_message(message: str, level: str = 'info', context: dict = None):
    """Manually capture a message to Sentry.
    
    Args:
        message: Message to capture
        level: Severity level (debug, info, warning, error, fatal)
        context: Additional context information
    """
    if context:
        with sentry_sdk.push_scope() as scope:
            for key, value in context.items():
                scope.set_context(key, value)
            sentry_sdk.capture_message(message, level=level)
    else:
        sentry_sdk.capture_message(message, level=level)


def set_user_context(user_id: str, email: str = None, username: str = None):
    """Set user context for Sentry events.
    
    Args:
        user_id: User ID
        email: User email (optional)
        username: Username (optional)
    """
    sentry_sdk.set_user({
        'id': user_id,
        'email': email,
        'username': username
    })


def add_breadcrumb(message: str, category: str = 'default', level: str = 'info', data: dict = None):
    """Add a breadcrumb for debugging.
    
    Args:
        message: Breadcrumb message
        category: Category (e.g., 'auth', 'query', 'navigation')
        level: Severity level
        data: Additional data
    """
    sentry_sdk.add_breadcrumb(
        message=message,
        category=category,
        level=level,
        data=data or {}
    )
